/**
 * @file AIAssistantSystem.vue
 * @description 智能交互式帮助系统，提供系统使用指导和问题解答
 * @created 2025-04-17
 */

<template>
  <div class="assistant-container">
    <div class="header-section">
      <h1>智能交互式帮助系统</h1>
      <p class="description">基于Dify的自然语言处理技术，为您提供智能化的系统使用指导</p>
      
      <!-- 调试按钮，仅在出现错误时显示 -->
      <div v-if="difyError" class="debug-tools">
        <button class="debug-btn" @click="testDifyConnection">测试Dify连接</button>
        <div v-if="connectionStatus.tested" class="connection-status">
          <div :class="['status-indicator', connectionStatus.status ? 'success' : 'error']"></div>
          <span>{{ connectionStatus.status ? '连接成功' : '连接失败' }}</span>
        </div>
      </div>
    </div>

    <!-- 主要聊天界面 -->
    <div class="chat-interface">
      <div class="chat-messages" ref="chatMessages">
        <div 
          v-for="(message, index) in messages" 
          :key="index" 
          :class="['message', message.sender]"
        >
          <div class="message-avatar">
            <div v-if="message.sender === 'assistant'" class="avatar assistant-avatar">🤖</div>
            <div v-else class="avatar user-avatar">👤</div>
          </div>
          <div class="message-content">
            <div class="message-text" v-html="formatMessage(message.text)"></div>
            <div v-if="message.sender === 'assistant'" class="message-feedback">
              <div class="feedback-question">这个回答对您有帮助吗？</div>
              <div class="feedback-buttons">
                <button class="feedback-btn thumbs-up" @click="sendFeedback(message.id, true)">
                  <i class="el-icon-thumb-up"></i> 有帮助
                </button>
                <button class="feedback-btn thumbs-down" @click="sendFeedback(message.id, false)">
                  <i class="el-icon-thumb-down"></i> 没帮助
                </button>
              </div>
            </div>
            <div v-if="message.sender === 'assistant' && message.actions && message.actions.length > 0" class="message-actions">
              <button 
                v-for="(action, actionIndex) in message.actions" 
                :key="actionIndex"
                class="action-button"
                @click="executeAction(action)"
              >
                {{ action.text }}
              </button>
            </div>
          </div>
        </div>
        <div v-if="isTyping" class="message assistant">
          <div class="message-avatar">
            <div class="avatar assistant-avatar">🤖</div>
          </div>
          <div class="message-content">
            <div class="typing-indicator">
              <span></span>
              <span></span>
              <span></span>
            </div>
          </div>
        </div>
      </div>
      
      <div class="chat-input">
        <div class="suggestions" v-if="showSuggestions && quickSuggestions.length > 0">
          <button 
            v-for="(suggestion, index) in quickSuggestions" 
            :key="index"
            class="suggestion-btn"
            @click="sendMessage(suggestion)"
          >
            {{ suggestion }}
          </button>
        </div>
        <div class="input-area">
          <input 
            type="text" 
            v-model="userInput" 
            placeholder="输入问题或指令..." 
            @keyup.enter="sendUserMessage"
            :disabled="isTyping"
          />
          <button class="send-btn" @click="sendUserMessage" :disabled="isTyping">
            <span>发送</span>
          </button>
        </div>
      </div>
    </div>

    <!-- 常见问题侧边栏 -->
    <div class="faq-sidebar">
      <h2>常见问题</h2>
      <div class="faq-list">
        <div 
          v-for="(faq, index) in faqList" 
          :key="index"
          class="faq-item"
          @click="sendMessage(faq.question)"
        >
          <div class="faq-icon">❓</div>
          <div class="faq-text">{{ faq.question }}</div>
        </div>
      </div>
      <div class="context-aware">
        <h3>上下文感知问题</h3>
        <div class="context-questions">
          <div 
            v-for="(question, index) in contextQuestions" 
            :key="index"
            class="context-item"
            @click="sendMessage(question)"
          >
            {{ question }}
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { v4 as uuidv4 } from 'uuid'
import { sendMessageToDifyStream } from '@/api/admin/ai/dify.js'

// Dify API连接错误状态
const difyError = ref(null)
// 连接状态
const connectionStatus = ref({
  tested: false,
  status: false,
  details: null
})

// 会话ID
const conversationId = ref('')
// 用户ID - 可从用户信息中获取或生成一个唯一的
const userId = ref('user_' + uuidv4())

// 聊天消息
const messages = ref([
  {
    id: uuidv4(),
    sender: 'assistant',
    text: '👋 你好！我是AI教学管理平台的智能助手。有什么可以帮助你的吗？',
    // actions: [ ... ] // actions 可以保留或根据Dify能力调整
  }
])

// 从localStorage尝试恢复会话ID
const loadSavedConversationId = () => {
  try {
    const savedId = localStorage.getItem('dify_conversation_id')
    if (savedId) {
      console.log('从存储中恢复会话ID:', savedId)
      conversationId.value = savedId
      return true
    }
  } catch (e) {
    console.error('从localStorage加载会话ID失败:', e)
  }
  return false
}

// 保存会话ID到localStorage
const saveConversationId = (id) => {
  try {
    if (id) {
      localStorage.setItem('dify_conversation_id', id)
      console.log('会话ID已保存到localStorage:', id)
    }
  } catch (e) {
    console.error('保存会话ID到localStorage失败:', e)
  }
}

// 用户输入
const userInput = ref('')
// 是否正在输入 (应为 isReceivingResponse 或类似名称，表示等待AI响应)
const isTyping = ref(false) // 改为 isWaitingForResponse 或 isLoading
// 是否显示建议
const showSuggestions = ref(true)
// 聊天区域引用
const chatMessages = ref(null)
// 当前正在接收的消息 (用于流式显示)
// const currentAnswer = ref('') // 将直接更新最后一条助手消息的text

// 快速建议
const quickSuggestions = ref([
  '如何使用AI教学系统？',
  '如何查看学生数据分析报告？',
  '如何管理用户权限？'
])

// 常见问题列表
const faqList = ref([
      { 
        question: '如何重置用户密码？',
        answer: '管理员可以在「用户管理」页面，找到对应用户，点击「重置密码」按钮进行操作。系统会生成一个临时密码并发送到用户的注册邮箱。'
      },
      { 
        question: '如何批量导入学生信息？',
        answer: '在「学生管理」页面，点击右上角的「批量导入」按钮，下载模板，填写后上传即可。系统支持Excel和CSV格式的文件导入。'
      },
      { 
        question: '如何分析教学质量？',
        answer: '进入「教学质量智能评估系统」，选择学院和学期，点击「生成评估报告」按钮。系统会自动分析教学数据并生成多维度的质量报告。'
      }
])

// 上下文感知问题
const contextQuestions = ref([
      '如何使用AI辅助决策分析系统？',
      '教学质量评估系统的指标是如何计算的？',
      '如何查看教师的教学风格分析？',
      '如何使用自然语言查询教学数据？'
])

// 滚动到底部
const scrollToBottom = () => {
  nextTick(() => {
    if (chatMessages.value) {
      chatMessages.value.scrollTop = chatMessages.value.scrollHeight
    }
  })
}

// 发送用户消息
const sendUserMessage = async () => {
  const query = userInput.value.trim()
  if (!query) return

  // 添加用户消息到列表
  messages.value.push({
    id: uuidv4(),
    sender: 'user',
    text: query
  })
  userInput.value = ''
  scrollToBottom()
  showSuggestions.value = false // 发送消息后可以隐藏建议

  await processQueryWithDify(query);
}

// 处理FAQ或建议点击发送消息
const sendMessage = async (query) => {
  if (!query.trim()) return

  messages.value.push({
    id: uuidv4(),
    sender: 'user',
    text: query
  })
  scrollToBottom()
  showSuggestions.value = false

  await processQueryWithDify(query);
}

// 核心：调用Dify API处理查询
const processQueryWithDify = async (query) => {
  isTyping.value = true // 表示正在等待AI响应
  difyError.value = null // 清除之前的错误

  // 为助手创建一个临时的消息占位符，用于流式更新
  const assistantMessageId = uuidv4()
  messages.value.push({
    id: assistantMessageId,
    sender: 'assistant',
    text: '', // 初始为空，流式填充
    isStreaming: true // 自定义属性，标记正在流式接收
  })
  scrollToBottom()

  let accumulatedAnswer = '';
  let finalConversationId = conversationId.value; // 开始时使用当前的会话ID

  try {
    await sendMessageToDifyStream(
      query,
      userId.value,
      conversationId.value, // 传入当前的会话ID
      (data) => { // onStreamData
        // console.log('Dify stream data:', data);
        const assistantMsgIndex = messages.value.findIndex(m => m.id === assistantMessageId);
        if (assistantMsgIndex === -1) return; // 应该不会发生

        if (data.event === 'message' || data.event === 'agent_message') {
          accumulatedAnswer += data.answer;
          messages.value[assistantMsgIndex].text = accumulatedAnswer;
          scrollToBottom();
        } else if (data.event === 'message_end') {
          // 消息结束事件，可以获取最终的元数据或用量信息
          console.log('Dify message_end:', data);
          if (data.conversation_id) {
            finalConversationId = data.conversation_id;
          }
          // 可以在这里处理 metadata 和 usage
        } else if (data.event === 'error') {
          console.error('Dify stream error event:', data);
          difyError.value = `流式传输错误: ${data.code} - ${data.message}`;
          messages.value[assistantMsgIndex].text = `抱歉，处理时遇到错误: ${data.message}`;
          messages.value[assistantMsgIndex].isError = true; // 标记错误消息
        }
        // 其他事件如 agent_thought, message_file 等可以按需处理
        
        // 更新会话ID（如果Dify在流的中间返回了新的conversation_id）
        if (data.conversation_id && data.conversation_id !== conversationId.value) {
            console.log('Dify stream updated conversation_id:', data.conversation_id);
            finalConversationId = data.conversation_id; // 存储从流中获取的最新会话ID
        }
      },
      (convIdFromEnd) => { // onStreamEnd
        console.log('Dify stream ended. Final Conversation ID:', convIdFromEnd || finalConversationId);
        isTyping.value = false;
        const assistantMsgIndex = messages.value.findIndex(m => m.id === assistantMessageId);
        if (assistantMsgIndex !== -1) {
          messages.value[assistantMsgIndex].isStreaming = false; // 标记流结束
          // 确保使用最后确定的会话ID
          if (convIdFromEnd && convIdFromEnd !== conversationId.value) {
             conversationId.value = convIdFromEnd;
             saveConversationId(convIdFromEnd);
          } else if (finalConversationId && finalConversationId !== conversationId.value) {
            conversationId.value = finalConversationId;
            saveConversationId(finalConversationId);
          }
        }
        scrollToBottom();
      },
      (error) => { // onError
        console.error('Dify API call failed:', error);
        isTyping.value = false;
        let displayErrorMessage = error.message || '连接Dify服务失败，请稍后再试。';

        // 检查是否是 "Conversation Not Exists" 错误
        if (error.message && error.message.includes('404') && error.message.toLowerCase().includes('conversation not exist')) {
          displayErrorMessage = '当前会话已失效，已为您重置。请重新发送您的问题。';
          conversationId.value = ''; // 清空当前会话ID
          localStorage.removeItem('dify_conversation_id'); // 从localStorage移除失效的ID
          console.log('失效的会话ID已清除，请用户重试。');
        }

        difyError.value = displayErrorMessage;
        const assistantMsgIndex = messages.value.findIndex(m => m.id === assistantMessageId);
        if (assistantMsgIndex !== -1) {
          messages.value[assistantMsgIndex].text = `抱歉，无法连接到AI助手: ${displayErrorMessage}`;
          messages.value[assistantMsgIndex].isError = true;
          messages.value[assistantMsgIndex].isStreaming = false;
        } else {
          messages.value.push({
            id: uuidv4(),
            sender: 'assistant',
            text: `抱歉，无法连接到AI助手: ${displayErrorMessage}`,
            isError: true,
          });
        }
        ElMessage.error(displayErrorMessage);
        scrollToBottom();
      }
    );
  } catch (e) {
    // 这个catch理论上不应该被触发，因为sendMessageToDifyStream内部处理了错误
    console.error('Unexpected error in processQueryWithDify:', e);
    isTyping.value = false;
    difyError.value = '发生意外错误，请查看控制台。';
    ElMessage.error(difyError.value);
    const assistantMsgIndex = messages.value.findIndex(m => m.id === assistantMessageId);
    if (assistantMsgIndex !== -1) {
      messages.value[assistantMsgIndex].text = `发生意外错误。`;
      messages.value[assistantMsgIndex].isError = true;
      messages.value[assistantMsgIndex].isStreaming = false;
    }
  }
}

// 格式化消息文本（例如，处理换行符）
const formatMessage = (text) => {
  if (typeof text !== 'string') return '';
  return text.replace(/\n/g, '<br>');
}

// 发送反馈 (这个可以保留，但实际的反馈API需要另外实现或连接到Dify的反馈机制)
const sendFeedback = (messageId, hilfreich) => {
  console.log(`Feedback for message ${messageId}: ${hilfreich ? '👍' : '👎'}`);
  // TODO: 调用API发送反馈
  ElMessage.success('感谢您的反馈！');
}

// 执行动作 (这个可以保留，但实际的动作执行逻辑需要实现)
const executeAction = (action) => {
  console.log('Executing action:', action);
  // TODO: 实现动作逻辑，例如导航到特定页面或执行特定功能
  if (action.action === 'guide') {
    sendMessage('请告诉我平台使用指南');
  } else if (action.action === 'features') {
    sendMessage('请介绍一下平台的主要功能');
  } else if (action.action === 'faq') {
    // 可以显示一个FAQ列表或发送一个查询
    sendMessage('常见问题有哪些？');
  } else {
    ElMessage.info(`将执行操作: ${action.text}`);
  }
}

// 测试Dify连接 (可以修改为调用一个简单的Dify查询)
const testDifyConnection = async () => {
  console.log('Testing Dify connection...');
  connectionStatus.value = { tested: true, status: false, details: '正在测试...' };
  isTyping.value = true; // 显示加载状态
  difyError.value = null;

  let tempConversationIdForTest = ''; // 测试不保存会话

  try {
    await sendMessageToDifyStream(
      '你好', // 一个简单的测试查询
      'test_user_' + uuidv4(),
      null, // 不传入 conversationId 进行新会话测试
      (data) => {
        if (data.event === 'message' && data.answer) {
          connectionStatus.value.status = true;
          connectionStatus.value.details = '连接成功，收到回复。';
          console.log('Dify connection test successful, response part:', data.answer);
        }
        if (data.conversation_id) {
            tempConversationIdForTest = data.conversation_id; // Dify会为新对话创建ID
        }
      },
      () => { // onStreamEnd
        isTyping.value = false;
        if (connectionStatus.value.status) {
          ElMessage.success('Dify连接测试成功！');
          console.log('Dify test conversation ID:', tempConversationIdForTest);
        } else {
          // 如果流结束了但没有收到有效消息
          connectionStatus.value.status = false;
          connectionStatus.value.details = '连接成功但未收到有效回复。';
           ElMessage.warning('Dify连接测试未收到预期回复。');
        }
      },
      (error) => { // onError
        isTyping.value = false;
        connectionStatus.value.status = false;
        connectionStatus.value.details = `连接失败: ${error.message}`;
        difyError.value = error.message;
        ElMessage.error(`Dify连接测试失败: ${error.message}`);
      }
    );
  } catch (e) {
    isTyping.value = false;
    connectionStatus.value.status = false;
    connectionStatus.value.details = `测试异常: ${e.message}`;
    difyError.value = e.message;
    ElMessage.error(`Dify连接测试发生异常: ${e.message}`);
  }
}

onMounted(() => {
  loadSavedConversationId(); // 组件挂载时加载已保存的会话ID
  // 可以移除或保留 fetchInitialData，取决于 quickSuggestions, faqList 等是否需要从API获取
  // fetchInitialData(); 
  scrollToBottom();
});

// 如果需要从API获取问题列表
// const fetchInitialData = async () => {
//   try {
//     // quickSuggestions.value = await getFrequentQuestions(); // 示例
//     // faqList.value = await getFaqList(); // 示例
//   } catch (error) {
//     console.error('获取初始数据失败:', error);
//     ElMessage.error('加载预设问题失败。');
//   }
// };
</script>

<style scoped>
.assistant-container {
  display: grid;
  grid-template-columns: 1fr 300px;
  gap: 20px;
  padding: 20px;
  background-color: #f0f2f5;
  min-height: 100vh;
}

.header-section {
  grid-column: 1 / -1;
  margin-bottom: 20px;
}

.header-section h1 {
  font-size: 28px;
  color: #1890ff;
  margin-bottom: 10px;
}

.description {
  color: #666;
}

.chat-interface {
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  height: calc(100vh - 150px);
}

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 20px;
}

.message {
  display: flex;
  margin-bottom: 20px;
}

.message.user {
  flex-direction: row-reverse;
}

.message-avatar {
  margin: 0 10px;
}

.avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
}

.assistant-avatar {
  background-color: #e6f7ff;
}

.user-avatar {
  background-color: #f9f9f9;
}

.message-content {
  max-width: 70%;
  padding: 12px 16px;
  border-radius: 8px;
  position: relative;
}

.message.assistant .message-content {
  background-color: #f0f2f5;
}

.message.user .message-content {
  background-color: #e6f7ff;
}

.message-text {
  line-height: 1.5;
}

.message-feedback {
  margin-top: 10px;
  font-size: 14px;
  color: #666;
  display: flex;
  flex-direction: column;
}

.feedback-question {
  margin-bottom: 5px;
}

.feedback-buttons {
  display: flex;
  gap: 10px;
}

.feedback-btn {
  background: transparent;
  border: 1px solid #d9d9d9;
  padding: 4px 8px;
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  font-size: 12px;
}

.feedback-btn:hover {
  border-color: #1890ff;
  color: #1890ff;
}

.message-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}

.action-button {
  padding: 6px 12px;
  background-color: white;
  border: 1px solid #1890ff;
  color: #1890ff;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
}

.action-button:hover {
  background-color: #e6f7ff;
}

.typing-indicator {
  display: flex;
  align-items: center;
  gap: 3px;
}

.typing-indicator span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #1890ff;
  display: inline-block;
  animation: typing 1.5s infinite ease-in-out;
}

.typing-indicator span:nth-child(1) {
  animation-delay: 0s;
}

.typing-indicator span:nth-child(2) {
  animation-delay: 0.3s;
}

.typing-indicator span:nth-child(3) {
  animation-delay: 0.6s;
}

@keyframes typing {
  0%, 60%, 100% {
    transform: translateY(0);
    opacity: 0.5;
  }
  30% {
    transform: translateY(-5px);
    opacity: 1;
  }
}

.chat-input {
  padding: 15px;
  border-top: 1px solid #f0f0f0;
}

.suggestions {
  display: flex;
  gap: 10px;
  margin-bottom: 10px;
  overflow-x: auto;
  padding-bottom: 10px;
}

.suggestion-btn {
  padding: 6px 12px;
  background-color: #f9f9f9;
  border: 1px solid #d9d9d9;
  border-radius: 16px;
  white-space: nowrap;
  cursor: pointer;
  font-size: 14px;
}

.suggestion-btn:hover {
  background-color: #f0f2f5;
  border-color: #1890ff;
  color: #1890ff;
}

.input-area {
  display: flex;
  gap: 10px;
}

.input-area input {
  flex: 1;
  padding: 10px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  outline: none;
}

.input-area input:focus {
  border-color: #1890ff;
}

.send-btn {
  padding: 0 20px;
  background-color: #1890ff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.send-btn:disabled {
  background-color: #d9d9d9;
  cursor: not-allowed;
}

.faq-sidebar {
  background-color: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  padding: 20px;
  height: calc(100vh - 150px);
  overflow-y: auto;
}

.faq-sidebar h2 {
  margin-top: 0;
  margin-bottom: 15px;
  font-size: 18px;
}

.faq-list {
  margin-bottom: 30px;
}

.faq-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px;
  border-radius: 4px;
  cursor: pointer;
  border-bottom: 1px solid #f0f0f0;
}

.faq-item:hover {
  background-color: #f9f9f9;
}

.faq-icon {
  color: #1890ff;
}

.faq-text {
  flex: 1;
  line-height: 1.5;
}

.context-aware h3 {
  margin-bottom: 15px;
  font-size: 16px;
}

.context-questions {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.context-item {
  padding: 10px;
  background-color: #f9f9f9;
  border-radius: 4px;
  cursor: pointer;
  line-height: 1.5;
}

.context-item:hover {
  background-color: #e6f7ff;
}

.debug-tools {
  margin-top: 10px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.debug-btn {
  padding: 6px 12px;
  background-color: #1890ff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.connection-status {
  display: flex;
  align-items: center;
  gap: 10px;
}

.status-indicator {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  display: inline-block;
}

.success {
  background-color: green;
}

.error {
  background-color: red;
}
</style>